package org.example.erat.parser;

import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.extractor.WordExtractor;
import org.example.erat.exception.FileParseException;
import org.example.erat.exception.InvalidFileNameException;
import org.example.erat.log.core.LoggerSingleton;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Word文件解析器
 * 用于解析.doc和.docx文件
 */
public class WordFileParser implements FileParser {

    // 支持多种文件名格式：
    // 1. 实验名_学号_姓名.doc|docx
    private static final Pattern FILE_NAME_PATTERN = Pattern.compile("(.+)_([0-9]+)_(.+)\\.(doc|docx)");

    @Override
    public Map<String, Object> parse(File file) throws IOException {
        LoggerSingleton.getInstance().info("开始解析Word文档: " + file.getName());

        // 解析文件名
        Map<String, String> fileNameInfo = extractInfoFromFileName(file.getName());
        if (fileNameInfo.isEmpty()) {
            throw new FileParseException("文件名格式不正确: " + file.getName());
        }

        // 解析Word文件内容
        List<String> paragraphs = new ArrayList<>();
        try (FileInputStream fis = new FileInputStream(file)) {
            if (file.getName().endsWith(".docx")) {
                // 解析.docx文件
                try (XWPFDocument document = new XWPFDocument(fis)) {
                    for (XWPFParagraph paragraph : document.getParagraphs()) {
                        String text = paragraph.getText();
                        if (text != null && !text.trim().isEmpty()) {
                            paragraphs.add(text);
                        }
                    }
                }
            } else {
                // 解析.doc文件
                try (HWPFDocument document = new HWPFDocument(fis);
                     WordExtractor extractor = new WordExtractor(document)) {
                    String[] extractedParagraphs = extractor.getParagraphText();
                    for (String paragraph : extractedParagraphs) {
                        if (paragraph != null && !paragraph.trim().isEmpty()) {
                            paragraphs.add(paragraph);
                        }
                    }
                }
            }
        } catch (Exception e) {
            LoggerSingleton.getInstance().error("解析Word文档失败: " + e.getMessage(), e);
            throw new FileParseException("解析Word文档失败: " + e.getMessage(), e);
        }

        Map<String, Object> result = new HashMap<>();
        result.put("fileName", file.getName());
        result.put("filePath", file.getAbsolutePath());
        result.put("fileSize", file.length());
        result.put("paragraphs", paragraphs);
        result.put("experimentName", fileNameInfo.get("experimentName"));
        result.put("studentId", fileNameInfo.get("studentId"));
        result.put("studentName", fileNameInfo.get("studentName"));

        LoggerSingleton.getInstance().info("Word文档解析完成: " + file.getName() + ", 共 " + paragraphs.size() + " 个段落");
        return result;
    }

    @Override
    public String getSupportedFileType() {
        return "docx";
    }

    @Override
    public boolean validateFileName(String fileName) {
        return FILE_NAME_PATTERN.matcher(fileName).matches();
    }

    @Override
    public Map<String, String> extractInfoFromFileName(String fileName) {
        Map<String, String> result = new HashMap<>();

        Matcher matcher = FILE_NAME_PATTERN.matcher(fileName);
        if (matcher.matches()) {
            String experimentName = matcher.group(1);
            String studentId = matcher.group(2);
            String studentName = matcher.group(3);

            result.put("experimentName", experimentName);
            result.put("studentId", studentId);
            result.put("studentName", studentName);
        } else {
            LoggerSingleton.getInstance().warn("文件名格式不正确: " + fileName + "，应为: 实验名_学号_姓名.doc或实验名_学号_姓名.docx");
            throw new InvalidFileNameException("文件名格式不正确: " + fileName + "，应为: 实验名_学号_姓名.doc或实验名_学号_姓名.docx");
        }

        return result;
    }
}
